package com.dony.order.service.impl;

import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dony.common.utils.StringUtils;
import com.dony.common.utils.file.OssUtils;
import com.dony.order.domain.Order;
import com.dony.order.mapper.OrderMapper;
import com.dony.order.service.ILogisticsService;
import com.dony.order.service.IOrderService;
import com.dony.shop.util.ShopeeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

/**
 * 物流Service业务层处理
 *
 * @author dony
 * @date 2023-09-07
 */
@Slf4j
@Service("logisticsService")
public class LogisticsServiceImpl extends ServiceImpl<OrderMapper, Order> implements ILogisticsService {

    @Autowired
    ShopeeUtil shopeeUtil;
    @Resource
    IOrderService orderService;
    @Resource
    ThreadPoolTaskExecutor executor;


    /**
     * 15天内的订单，批量保存
     *
     * @param shopId
     * @return
     */
//    public Boolean batchSaveDocument(Long shopId) {
//        //当前时间
//        long timestamp = System.currentTimeMillis() / 1000L;
//        //15天前的时间
//        long gap = 15 * 24 * 60 * 60;
//        return batchSaveDocument(shopId, timestamp - gap, timestamp);
//    }

    /**
     * 获取发货参数
     *
     * @param shopId
     * @param orderSn
     * @return
     */
    public JSONObject getShippingParameter(Long shopId, String orderSn) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("order_sn", orderSn);
        JSONObject response = shopeeUtil.shopGetHandler("/api/v2/logistics/get_shipping_parameter", shopId, paramMap);
        if (response == null) {
            log.error("获取发货参数调用失败！订单号：" + orderSn);
        }
        return response;
    }


    @Override
    public Boolean shipOrder(Long shopId, String orderSn) {
        Map<String, Object> paramMap = new HashMap<>();
        //获取发货参数
        JSONObject shippingParameter = getShippingParameter(shopId, orderSn);
        JSONObject info_needed = shippingParameter.getJSONObject("info_needed");
        if (info_needed.getJSONArray("dropoff") != null) {
            //封装参数
            Map<String, Object> dropoff = new HashMap<>();
            info_needed.getJSONArray("dropoff").forEach(d -> {
                MapUtil.of(d.toString(), null);
            });
            paramMap.put("dropoff", dropoff);
        }
        if (info_needed.getJSONArray("pickup") != null) {
            //封装参数
            Map<String, Object> pickup = new HashMap<>();
            info_needed.getJSONArray("pickup").forEach(p -> {
                MapUtil.of(p.toString(), null);
            });
            paramMap.put("pickup", pickup);
        }
        paramMap.put("order_sn", orderSn);
        JSONObject response = shopeeUtil.shopPostHandler("/api/v2/logistics/ship_order", shopId, paramMap);
        if (response == null) {
            return false;
        }
        return true;
    }


    /**
     * 获取运单号
     *
     * @param shopId
     * @param sn
     * @return
     */
    @Override
    public String getTrackingNumber(Long shopId, String sn) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("order_sn", sn);
        JSONObject response = shopeeUtil.shopGetHandler("/api/v2/logistics/get_tracking_number", shopId, paramMap);
        if (response == null) {
            return null;
        }
        return response.getString("tracking_number");
    }


    /**
     * 获取面单的参数
     *
     * @param shopId
     * @param orderSns
     * @return
     */
    @Override
    public Boolean getShippingDocumentParameter(Long shopId, List<String> orderSns) {
        Map<String, Object> paramMap = new HashMap<>();
        List<Map<String, Object>> mapList = orderSns.stream().map(sn -> {
            //获取运单号
            Map<String, Object> snMap = new HashMap<>();
            snMap.put("order_sn", sn);
            //this.getTrackingNumber(shopId, sn);
            return snMap;
        }).collect(Collectors.toList());
        paramMap.put("order_list", mapList);
        JSONObject response = shopeeUtil.shopPostHandler("/api/v2/logistics/get_shipping_document_parameter", shopId, paramMap);
        return response != null;
    }


    /**
     * 创建面单
     *
     * @param orderSns
     * @return
     */
    @Override
    public Boolean createShippingDocument(List<String> orderSns) {
        try {
            // 使用CompletableFuture进行异步处理
            List<CompletableFuture<Boolean>> futures = orderSns.stream()
                    .map(ordersn -> CompletableFuture.supplyAsync(() -> createShippingDocumentForOrder(ordersn), executor))
                    .collect(Collectors.toList());

            // 获取所有CompletableFuture的结果
            CompletableFuture<Void> allOf = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
            allOf.get();

            return futures.stream().allMatch(CompletableFuture::join);
        } catch (InterruptedException | ExecutionException e) {
            log.error("整体创建面单失败！错误：{}", e);
            return false;
        }
    }

    private Boolean createShippingDocumentForOrder(String ordersn) {
        try {
            Order order = orderService.getById(ordersn);
            Map<String, Object> paramMap = new HashMap<>();
            List<Map<String, Object>> mapList = new ArrayList<>();
            Map<String, Object> snMap = new HashMap<>();
            snMap.put("order_sn", ordersn);
            snMap.put("tracking_number", this.getTrackingNumber(order.getShopId(), ordersn));
            mapList.add(snMap);
            paramMap.put("order_list", mapList);
            JSONObject response = shopeeUtil.shopPostHandler("/api/v2/logistics/create_shipping_document", order.getShopId(), paramMap);

            return response != null;
        } catch (Exception e) {
            log.error("订单{}，创建面单失败！错误：{}", ordersn, e);
            return false;
        }
    }

    @Override
    public Boolean tryGetShippingDocumentResult(List<String> snList, int maxAttempts) {
        do {
            maxAttempts--;
            if (getShippingDocumentResult(snList)) {
                return true;
            }
        } while (maxAttempts > 0);
        return false;
    }


    /**
     * 获取创建结果，可以打印的订单
     *
     * @param orderSns
     * @return
     */
    @Override
    public Boolean getShippingDocumentResult(List<String> orderSns) {
        try {
            // 使用CompletableFuture进行异步处理
            List<CompletableFuture<Boolean>> futures = orderSns.stream()
                    .map(ordersn -> CompletableFuture.supplyAsync(() -> processGetShippingDocumentResult(ordersn), executor))
                    .collect(Collectors.toList());

            // 获取所有CompletableFuture的结果
            CompletableFuture<Void> allOf = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
            allOf.get(); // 等待所有任务完成

            // 检查所有任务的结果
            return futures.stream().allMatch(CompletableFuture::join);
        } catch (InterruptedException | ExecutionException e) {
            log.error("整体获取面单结果失败！错误：{}", e);
            return false;
        }
    }


    private Boolean processGetShippingDocumentResult(String ordersn) {
        try {
            Order order = orderService.getById(ordersn);
            Map<String, Object> paramMap = new HashMap<>();
            List<Map<String, Object>> mapList = new ArrayList<>();
            Map<String, Object> snMap = new HashMap<>();
            snMap.put("order_sn", ordersn);
            mapList.add(snMap);
            paramMap.put("order_list", mapList);
            JSONObject response = shopeeUtil.shopPostHandler("/api/v2/logistics/get_shipping_document_result", order.getShopId(), paramMap);
            if (response == null) {
                return false;
            }
            List<JSONObject> resultList = response.getList("result_list", JSONObject.class);
            for (JSONObject res : resultList) {
                if (!StringUtils.equals(res.getString("status"), "READY")) {
                    return false;
                }
            }

            return true;
        } catch (Exception e) {
            log.error("订单{}，获取面单结果失败！错误：{}", ordersn, e);
            return false;
        }
    }


    @Override
    public byte[] downloadShippingDocument(Long shopId, String orderSn) {
        Map<String, Object> paramMap = new HashMap<>();
        List<Map<String, Object>> mapList = new ArrayList<>();
        Map<String, Object> snMap = new HashMap<>();
        snMap.put("order_sn", orderSn);
        mapList.add(snMap);
        paramMap.put("order_list", mapList);
        byte[] bytes = shopeeUtil.downloadFile("/api/v2/logistics/download_shipping_document", shopId, paramMap);
        //如果需要保存文件
        if (bytes.length < 10240) {
            log.error("订单：{}打印失败！文件太小！",orderSn);
            return null;
        }
        return bytes;
    }


    /**
     * 下载运单，并修改状态
     *
     * @param shopId
     * @param orderSns
     * @return
     */
//    public Boolean downloadShippingDocumentBatch(Long shopId, List<String> orderSns) {
//        orderSns.stream().forEach(sn -> {
//            downloadShippingDocument(shopId, sn);
//        });
//        return true;
//    }

//    /**
//     * post保存文件请求处理
//     *
//     * @param path
//     * @param shopId
//     * @param paramMap
//     * @param filePath
//     * @return
//     */
//    public Boolean pushFileToOss( String ossPath,byte[] data) {
//
//        log.info("文件上传至阿里云成功，文件名称：{}，大小：{}", ossPath,data.length);
//        return true;
//    }


    /**
     * 批量保存打印的订单
     *
     * @param shopId
     * @param timeFron
     * @param timeTo
     * @return
     */
//    public Boolean batchSaveDocument(Long shopId, Long timeFron, Long timeTo) {
//        //获取未保存的订单
//        QueryWrapper<Order> queryWrapper = new QueryWrapper<Order>().isNull("doc_url").eq("order_status", "PROCESSED")
//                .eq("shop_id", shopId).between("create_time", new Date(timeFron * 1000L), new Date(timeTo * 1000L));
//        List<Order> orderList = this.list(queryWrapper);
//        if (orderList == null || orderList.size() == 0) {
//            return false;
//        }
//        //分批处理
//        for (int i = 0; i <= orderList.size() / 50; i++) {
//            int firstIndex = i * 50;
//            int lastIndex = orderList.size() / 50 == i ? orderList.size() : (i + 1) * 50;
//            List<String> sns = orderList.subList(firstIndex, lastIndex).stream().map(Order::getOrderSn).collect(Collectors.toList());
//            this.createShippingDocument(shopId, sns);
//            this.getShippingDocumentResult(shopId, sns);
//            this.downloadShippingDocumentBatch(shopId, sns);
//        }
//        return true;
//    }


}
